/*!
 * \file frtds_convert.h
 *
 * \brief tds协议共通
 *
 * All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.\n
 * tds协议共通接口
 *
 * \version 2.0
 * \author zhengxd
 * \date 2015/05/29
 *
 */

#ifndef __FRFRTDS_CONVERT_H_
#define __FRFRTDS_CONVERT_H_

#define FRTDS_MSSQL               0
#define FRTDS_SYBASE              1

#define FRTDS_DIRECT_UNKNOWN      0      /* 未知方向 */
#define FRTDS_DIRECT_REQUEST      1      /* request方向 */
#define FRTDS_DIRECT_RESPONSE     2      /* response方向 */

#define FRTDS_PACKET_HEAD_LEN     8      /* PACKET header的长度 */

#define FRTDS_SYBASE_UNKNOW       0      /* 不能区分是sybase还是mssql */
#define FRTDS_SYBASE_YES          1      /* 是sybase */
#define FRTDS_SYBASE_NO           2      /* 肯定不是sybase，认为是mssql */

# if __WORDSIZE == 64
    #define PRI64D "%ld"
    #define PRI64U "%lu"
# else
__extension__
    #define PRI64D "%lld"
    #define PRI64U "%llu"
# endif

typedef enum __frtds_type_float {
    FRTDS_FLT_IEEE_HI = 0,
    FRTDS_FLT_VAXD,
    FRTDS_FLT_IEEE_LO,
    FRTDS_FLT_ND5000,
} Frtds_type_float;

typedef enum __frtds_lnoshort {
    FRTDS_NOCVT_SHORT = 0,
    FRTDS_CVT_SHORT,
} Frtds_lnoshort;

/*!
 * 释放参数
 *
 * \param pp_st_value         (Frdata_field **)
 *
 */
void frtds_free_param(Frdata_field **pp_st_value);

/*!
 * 释放参数
 *
 * \param p_value             (参数值)
 * \param i_date_type         (参数类型)
 * \param pp_st_value         (Frdata_field **)
 *
 * \return APM_L7_ANALYZE_SUCC:成功\n
 *         APM_L7_ANALYZE_FAIL:失败
 *
 * \note pp_st_value必须不为NULL
 *
 */
int frtds_create_param(char *p_value
                      , int i_date_type
                      , Frdata_field **pp_st_value);

/*!
 * 判断当前TDS是否属于SYBASE
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param i_packet_type         (packet type)
 * \param i_packet_type         (方向)
 *
 * \return FRTDS_SYBASE_NO:不是\n
 *         FRTDS_SYBASE_YES:是\n
 *         FRTDS_SYBASE_UNKNOW:未知
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_detect_sybase(Frbyte_Packet *p_st_data
                       , int i_whole_flg
                       , int i_packet_type
                       , int *p_i_req_resp);

/*!
 * 解析整型
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param i_endian              (字节序)
 * \param ui_int_len            (表示int型所占据的字节数)
 * \param i_unsigned_flg        (是否是unsigned的标识)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_int(Frbyte_Packet *p_st_data
                        , int i_whole_flg
                        , LITTLE_BIG_ENDIAN i_endian
                        , unsigned int ui_int_len
                        , int i_unsigned_flg
                        , Frdata_field **pp_st_value);

/*!
 * 解析整型
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param i_endian              (字节序)
 * \param i_unsigned_flg        (是否是unsigned的标识)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_intn(Frbyte_Packet *p_st_data
                         , int i_whole_flg
                         , LITTLE_BIG_ENDIAN i_endian
                         , int i_unsigned_flg
                         , Frdata_field **pp_st_value);

/*!
 * 解析boolean
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_boolean(Frbyte_Packet *p_st_data
                            , int i_whole_flg
                            , Frdata_field **pp_st_value);

/*!
 * 解析booleann
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_booleann(Frbyte_Packet *p_st_data
                             , int i_whole_flg
                             , Frdata_field **pp_st_value);

/*!
 * 解析datetime
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param ui_datetime_len       (表示DateTime型所占据的字节数)
 * \param i_endian              (字节序)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_datetime(Frbyte_Packet *p_st_data
                             , unsigned int ui_datetime_len
                             , LITTLE_BIG_ENDIAN i_endian
                             , int i_whole_flg
                             , Frdata_field **pp_st_value);

/*!
 * 解析datetimen
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param i_endian              (字节序)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_datetimen(Frbyte_Packet *p_st_data
                              , LITTLE_BIG_ENDIAN i_endian
                              , int i_whole_flg
                              , Frdata_field **pp_st_value);

/*!
 * 解析date
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param ui_date_len           (表示Date型所占据的字节数)
 * \param i_endian              (字节序)
 * \param i_db_type             (数据库类型)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_date(Frbyte_Packet *p_st_data
                         , unsigned int ui_date_len
                         , LITTLE_BIG_ENDIAN i_endian
                         , int i_db_type
                         , int i_whole_flg
                         , Frdata_field **pp_st_value);

/*!
 * 解析daten
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param i_endian              (字节序)
 * \param i_db_type             (数据库类型)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_daten(Frbyte_Packet *p_st_data
                          , LITTLE_BIG_ENDIAN i_endian
                          , int i_db_type
                          , int i_whole_flg
                          , Frdata_field **pp_st_value);

/*!
 * 解析time
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param ui_time_len           (表示time型所占据的字节数)
 * \param i_endian              (字节序)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_time(Frbyte_Packet *p_st_data
                         , unsigned int ui_time_len
                         , LITTLE_BIG_ENDIAN i_endian
                         , int i_whole_flg
                         , Frdata_field **pp_st_value);

/*!
 * 解析timen
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param i_endian              (字节序)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_timen(Frbyte_Packet *p_st_data
                          , LITTLE_BIG_ENDIAN i_endian
                          , int i_whole_flg
                          , Frdata_field **pp_st_value);

/*!
 * 解析mssql的timen
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param ui_scale              (scale)
 * \param i_endian              (字节序)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_mssql_timen(Frbyte_Packet *p_st_data
                                , unsigned int ui_scale
                                , LITTLE_BIG_ENDIAN i_endian
                                , int i_whole_flg
                                , Frdata_field **pp_st_value);

/*!
 * 把DateTimes的数据转成字符串
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param ui_scale              (scale)
 * \param ui_zone_len           (时区信息长度:0/2)
 * \param i_endian              (字节序)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_get_datetimes(Frbyte_Packet *p_st_data
                       , int ui_scale
                       , int ui_zone_len
                       , LITTLE_BIG_ENDIAN i_endian
                       , int i_whole_flg
                       , Frdata_field **pp_st_value);

/*!
 * 解析浮点型数据
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param ui_float_len          (表示float所占据的字节数)
 * \param i_float_type          (浮点数类型)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_float(Frbyte_Packet *p_st_data
                          , unsigned int ui_float_len
                          , Frtds_type_float i_float_type
                          , int i_whole_flg
                          , Frdata_field **pp_st_value);

/*!
 * 解析浮点型数据
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param i_float_type          (浮点数类型)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_floatn(Frbyte_Packet *p_st_data
                           , Frtds_type_float i_float_type
                           , int i_whole_flg
                           , Frdata_field **pp_st_value);

/*!
 * 解析varchar
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param i_endian              (字节序)
 * \param ui_len_bytes          (长度位占据的byte数)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_varchar(Frbyte_Packet *p_st_data
                            , int i_whole_flg
                            , LITTLE_BIG_ENDIAN i_endian
                            ,unsigned int ui_len_bytes
                            , Frdata_field **pp_st_value);

/*!
 * 解析Money
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param i_endian              (字节序)
 * \param ui_money_len          (money数据占据的长度)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_money(Frbyte_Packet *p_st_data
                          , int i_whole_flg
                          , LITTLE_BIG_ENDIAN i_endian
                          , unsigned int ui_money_len
                          , Frdata_field **pp_st_value);

/*!
 * 跳过固定长度位
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param ui_len                (要跳过的长度位)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_skip_fixed_len(Frbyte_Packet *p_st_data
                         , int i_whole_flg
                         , unsigned int ui_len);

/*!
 * 跳过固定长度位
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param i_endian              (字节序)
 * \param ui_var_len            (要跳过的长度位的长度)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_skip_var_len(Frbyte_Packet *p_st_data
                       , int i_whole_flg
                       , LITTLE_BIG_ENDIAN i_endian
                       , unsigned int ui_var_len);

/*!
 * 解析Moneyn
 *
 * \param p_st_data             (Frbyte_Packet *)
 * \param i_whole_flg           (数据包是否已经接收完成)
 * \param i_endian              (字节序)
 * \param pp_st_value           (出力数据)
 *
 * \return APM_L7_ANALYZE_FAIL:失败\n
 *         APM_L7_ANALYZE_TODO:数据不足\n
 *         APM_L7_ANALYZE_SUCC:成功
 *
 * \note p_st_data肯定不为NULL
 *
 */
int frtds_convert_to_moneyn(Frbyte_Packet *p_st_data
                           , int i_whole_flg
                           , LITTLE_BIG_ENDIAN i_endian
                           , Frdata_field **pp_st_value);

#endif
